﻿#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include "SDL.h"
#include "SDL_main.h"
#include "SDL_stdinc.h"
#include "SDL_mutex.h"
#include "SDL_messagebox.h"
#include "platform.h"
#include "init.h"

struct INFO {
	unsigned int signal;
	unsigned int coresize;
	unsigned int packsize;
};
char* ggelua = NULL;
char* ggepack = NULL;
struct INFO info = { 0,0,0 };

static int GGE_Load(lua_State* L)
{
    SDL_RWops *ops = SDL_RWFromFile("ggelua.lua", "r");
    if (ops) {
        info.coresize = SDL_RWsize(ops);
        info.packsize = 0;
        ggelua = (char*)SDL_malloc(info.coresize);
        SDL_RWread(ops, ggelua, info.coresize, 1);
        SDL_RWclose(ops);
    }

	return 0;
}

static int GGE_Error(lua_State* L) {
	lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);//LOADED
	if (lua_getfield(L, -1, "SDL") != LUA_TTABLE) {
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "error", lua_tostring(L, -3), NULL);
	}
	else {
		printf("%s\n", lua_tostring(L, -3));
	}
	return 0;
}

int main(int argc, char *argv[])
{
	lua_State* L = luaL_newstate();
	luaL_openlibs(L);
	lua_newtable(L);
	lua_createtable(L, argc, 0);
	for (int i = 1; i < argc; i++) {
		lua_pushstring(L, argv[i]);
		lua_seti(L, -2, i);
	}
	lua_setfield(L, -2, "arg");//gge.arg
#ifdef _CONSOLE
	lua_pushboolean(L, 1);
#else
	lua_pushboolean(L, 0);
#endif
	lua_setfield(L, -2, "isconsole");   //gge.isconsole
	lua_pushboolean(L, ggepack == NULL);
	lua_setfield(L, -2, "isdebug");     //gge.isdebug
	lua_pushstring(L, "main");
	lua_setfield(L, -2, "entry");       //gge.entry
	lua_pushboolean(L, 1);
	lua_setfield(L, -2, "ismain");      //gge.ismain
    lua_createtable(L, 6, 0);
    lua_pushinteger(L, GGE_TARGET_PLATFORM);
    lua_setfield(L, -2, "platform");    //gge.sys.platform
    lua_pushinteger(L, GGE_PLATFORM_IOS);
    lua_setfield(L, -2, "GGE_PLATFORM_IOS");    //gge.sys.GGE_PLATFORM_IOS
    lua_pushinteger(L, GGE_PLATFORM_ANDROID);
    lua_setfield(L, -2, "GGE_PLATFORM_ANDROID");    //gge.sys.GGE_PLATFORM_ANDROID
    lua_pushinteger(L, GGE_PLATFORM_WIN32);
    lua_setfield(L, -2, "GGE_PLATFORM_WIN32");    //gge.sys.GGE_PLATFORM_WIN32
    lua_pushinteger(L, GGE_PLATFORM_LINUX);
    lua_setfield(L, -2, "GGE_PLATFORM_LINUX");    //gge.sys.GGE_PLATFORM_LINUX
    lua_pushinteger(L, GGE_PLATFORM_MAC);
    lua_setfield(L, -2, "GGE_PLATFORM_MAC");    //gge.sys.GGE_PLATFORM_MAC
    lua_setfield(L, -2, "sys");//gge.sys
	lua_pushvalue(L, -1);
	lua_setfield(L, LUA_REGISTRYINDEX, "_ggelua");
	lua_setglobal(L, "gge");

	SDL_mutex** extra = (SDL_mutex**)lua_getextraspace(L);//线程锁
	SDL_mutex* mutex = SDL_CreateMutex();
	*extra = mutex;

    (argc == 2) ? lua_pushstring(L, argv[1]) : lua_pushstring(L, "");

    gge_init(L);

	lua_pushcfunction(L, GGE_Load);//读取脚本
	lua_pushstring(L, argv[0]);
	lua_call(L, 1, 0);

	if (ggelua) {
		lua_pushlstring(L, ggelua, info.coresize);
		lua_setfield(L, LUA_REGISTRYINDEX, "ggelua.lua");
		if (ggepack) {
			lua_pushlstring(L, ggepack, info.packsize);
			lua_setfield(L, LUA_REGISTRYINDEX, "ggepack");
		}
		SDL_LockMutex(mutex);//ggelua.delay解锁

		if (luaL_loadbuffer(L, ggelua, info.coresize, "ggelua.lua") == LUA_OK) {
			lua_pushstring(L, "main");
			if (ggepack)//打包的脚本数据
				lua_pushlstring(L, ggepack, info.packsize);
			else
				lua_pushnil(L);
			if (lua_pcall(L, 2, 0, 0) != LUA_OK) {
				GGE_Error(L);
			}
		}
		else
			GGE_Error(L);

		SDL_free(ggelua);
	}

	SDL_DestroyMutex(mutex);
	lua_close(L);

	if (ggepack)
		SDL_free(ggepack);
	return 0;
}
